package com.ins1st.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.ins1st.exception.AuthException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Calendar;

/**
 * @program: ins1st-cloud
 * @description:
 * @author: coderSun
 * @create: 2019-11-15 14:45
 **/
public class Jwt {

    /**
     * 加密字符串
     */
    private static final String SECRET = "ins1st@2!34%83*";

    /**
     * 发布者
     */
    private static final String ISSUER = "ins1st";

    /**
     * 用户账号
     */
    private static final String USER_NAME = "USER_NAME";
    /**
     * 用户密码
     */
    private static final String USER_PASSWORD = "USER_PASSWORD";

    private static final Logger log = LoggerFactory.getLogger(Jwt.class);

    /**
     * 创建token
     *
     * @param userName
     * @param userPassword
     * @return
     */
    public static String createToken(String userName, String userPassword) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, 1);
        Algorithm algorithm = Algorithm.HMAC256(SECRET);
        JWTCreator.Builder builder = JWT.create()
                .withIssuer(ISSUER)
                .withExpiresAt(calendar.getTime())
                .withClaim(USER_NAME, userName)
                .withClaim(USER_PASSWORD, userName);
        String token = builder.sign(algorithm);
        log.info("用户ID: {} ,创建token: {} ", userName, token);
        return token;
    }

    /**
     * 校验token
     *
     * @param token
     * @param userName
     * @param userPassword
     * @return
     */
    public static boolean verifyToken(String token, String userName, String userPassword) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            JWTVerifier verifier = JWT.require(algorithm).withIssuer(ISSUER).build();
            DecodedJWT jwt = verifier.verify(token);
            if (!StringUtils.equals(jwt.getIssuer(), ISSUER)) {
                throw new AuthException("token发布者错误");
            }
            if (!StringUtils.equals(jwt.getClaim(USER_NAME).asString(), userName)
                    && !StringUtils.equals(jwt.getClaim(USER_PASSWORD).asString(), userPassword)) {
                throw new AuthException("令牌不属于该用户");
            }
        } catch (TokenExpiredException e) {
            throw new AuthException("令牌已过期");
        } catch (SignatureVerificationException e) {
            throw new AuthException("令牌解析错误");
        }
        return true;
    }
}
